/*
 *
 * Paros and its related class files.
 * 
 * Paros is an HTTP/HTTPS proxy for assessing web application security.
 * Copyright (C) 2003-2004 Chinotec Technologies Company
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the Clarified Artistic License
 * as published by the Free Software Foundation.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * Clarified Artistic License for more details.
 * 
 * You should have received a copy of the Clarified Artistic License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

package org.parosproxy.paros.core.spider;

import java.util.regex.Pattern;

import org.apache.commons.httpclient.URI;
import org.parosproxy.paros.common.AbstractParam;

/**
 * 
 * To change the template for this generated type comment go to Window -
 * Preferences - Java - Code Generation - Code and Comments
 */
public class SpiderParam extends AbstractParam {

	private static final String SPIDER_MAX_DEPTH = "spider.maxDepth";
	private static final String SPIDER_THREAD = "spider.thread";
	private static final String SPIDER_SCOPE = "spider.scope";
	private static final String SPIDER_POST_FORM = "spider.postform";
	private static final String SPIDER_SKIP_URL = "spider.skipurl";

	private int maxDepth = 5;
	private int thread = 2;
	private String scope = "";
	private int postForm = 0;
	private String skipURL = "";
	private Pattern patternSkipURL = null;
	private Pattern patternScope = null;

	/**
	 * @param rootElementName
	 */
	public SpiderParam() {
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.proofsecure.paros.common.FileXML#parse()
	 */
	protected void parse() {

		try {
			setThread(getConfig().getInt(SPIDER_THREAD, 2));
		} catch (Exception e) {
		}
		try {
			setMaxDepth(getConfig().getInt(SPIDER_MAX_DEPTH, 5));
		} catch (Exception e) {
		}
		try {
			setPostForm(getConfig().getInt(SPIDER_POST_FORM, 0) != 0);
		} catch (Exception e) {
		}
		setScope(getConfig().getString(SPIDER_SCOPE, ""));
		setSkipURL(getConfig().getString(SPIDER_SKIP_URL, ""));

	}

	/**
	 * @return Returns the maxDepth.
	 */
	public int getMaxDepth() {
		return maxDepth;
	}

	/**
	 * @param maxDepth
	 *            The maxDepth to set.
	 */
	public void setMaxDepth(int maxDepth) {
		this.maxDepth = maxDepth;
		getConfig().setProperty(SPIDER_MAX_DEPTH,
				Integer.toString(this.maxDepth));

	}

	/**
	 * @return Returns the scope.
	 */
	public String getScope() {
		return scope;
	}

	/**
	 * @param scope
	 *            The scope to set.
	 */
	public void setScope(String scope) {
		this.scope = scope;
		getConfig().setProperty(SPIDER_SCOPE, this.scope);
		parseScope(this.scope);
	}

	/**
	 * @return Returns the thread.
	 */
	public int getThread() {
		return thread;
	}

	/**
	 * @param thread
	 *            The thread to set.
	 */
	public void setThread(int thread) {
		this.thread = thread;
		getConfig().setProperty(SPIDER_THREAD, Integer.toString(this.thread));

	}

	/**
	 * Check if given host name need to send using proxy.
	 * 
	 * @param hostName
	 *            host name to be checked.
	 * @return true = need to send via proxy.
	 */
	public boolean isInScope(String hostName) {
		if (patternScope == null || hostName == null) {
			return false;
		}

		return patternScope.matcher(hostName).find();
	}

	/**
	 * Parse the proxy chain skip text string and build the regex pattern.
	 */
	private void parseScope(String scope) {
		patternScope = null;

		if (scope == null || scope.equals("")) {
			return;
		}

		scope = scope.replaceAll("\\.", "\\\\.");
		scope = scope.replaceAll("\\*", ".*?").replaceAll("(;+$)|(^;+)", "");
		scope = "(" + scope.replaceAll(";+", "|") + ")$";
		patternScope = Pattern.compile(scope, Pattern.CASE_INSENSITIVE);
	}

	public boolean isPostForm() {
		return (postForm != 0);
	}

	public void setPostForm(boolean postForm) {
		if (postForm) {
			this.postForm = 1;
		} else {
			this.postForm = 0;
		}
		getConfig().setProperty(SPIDER_POST_FORM,
				Integer.toString(this.postForm));

	}

	public void setSkipURL(String skipURL) {
		this.skipURL = skipURL;
		getConfig().setProperty(SPIDER_SKIP_URL, this.skipURL);
		parseSkipURL(this.skipURL);

	}

	public boolean isSkipURL(URI uri) {

		if (patternSkipURL == null || uri == null) {
			return false;
		}
		String sURI = uri.toString();
		return patternSkipURL.matcher(sURI).find();

	}

	private void parseSkipURL(String skipURL) {
		patternSkipURL = null;

		if (skipURL == null || skipURL.equals("")) {
			return;
		}

		skipURL = skipURL.replaceAll("\\.", "\\\\.");
		skipURL = skipURL.replaceAll("\\*", ".*?").replaceAll(
				"(\\s+$)|(^\\s+)", "");
		skipURL = "\\A(" + skipURL.replaceAll("\\s+", "|") + ")";
		patternSkipURL = Pattern.compile(skipURL, Pattern.CASE_INSENSITIVE
				| Pattern.MULTILINE);

	}

	public String getSkipURL() {
		return skipURL;
	}
}
